/*
 * CreatureAIData.h
 *
 *  Created on: 2017��3��20��
 *      Author: gaoyi
 */


#pragma once

#include "Character/Creature.h"
#include "Common/Event/Event.h"
#include "Character/SkillPart.h"
#include "base/core/utility.h"

class AiData_ForCreature
{
public:
	AiData_ForCreature(Creature* pMaster = nullptr) :m_pMaster(pMaster)
	{

	}

	Creature*	GetMaster() { return m_pMaster; }
	void	SetMaster(Creature* pMon) { m_pMaster = pMon; }
protected:
	Creature*	m_pMaster;
};

class AiData_ForPatrolRandomPos : public AiData_ForCreature
{
public:
	AiData_ForPatrolRandomPos(Creature* master = nullptr) :AiData_ForCreature(master)
	{
		Clear();
		m_activeRange = 0;
	}

	void Clear();
public:
	bool	IsSetRandomTargetPos();
	void	SetRandomTargetPos();
	void  SetTargetPos(const Point3<float>& pos);
	bool 	IsReachTargetPos();
	void 	ReachTargetPos();
	bool 	MoveToTargetPos();

	Point3<float> GetTargetPos() { return m_targetPos; }
	Point3<float> GetLastTargetPos() { return m_lastTargetPos; }
	void SetLastTargetPos(const Point3<float>& homePos) { m_lastTargetPos = homePos; }

	void	SetActiveRange(float range) { m_activeRange = range; }
	void  SetHomePos(const Point3<float>& homePos) { m_homePos = homePos; }
private:
	Point3<float>	m_targetPos;
	Point3<float>	m_lastTargetPos;
	float				m_activeRange;
	Point3<float>  m_homePos;
};

class AiData_ForPatrolPath : public AiData_ForCreature
{
public:
	AiData_ForPatrolPath(Creature* master = nullptr) :AiData_ForCreature(master)
	{
		Clear();
	}

	void Clear();
	Point3<float> GetNeastPos(const Point3<float>& pos);
	bool IsFinish() const { return m_isFinish; }
	void AddPatrolPath(const std::vector<Point3<float> >& vecPos, int8_t patroType);
	int8_t GetPatrolType() const { return m_patroType; }
	const std::vector<Point3<float>>& GetPatrolPath() const { return m_patrolPath; }
public:
	bool IsReachNextPatrolPath();
	bool MoveToNextPatrolPath();
	void SetNextPatrolPath();
	bool HasPatrolPath() { return !m_patrolPath.empty(); }
	Point3<float> GetTargetPos();
	bool IsMoveToTarget() const { return m_moveToTarget; }
	void SetIsMoveToTarget(bool m) { m_moveToTarget = m; }
	uint32_t GetNextPatrolPathIndex() const { return m_nextPatrolPathIndex; }
	void SetNextPatrolPathIndex(uint32_t index) { m_nextPatrolPathIndex = index; }
	float GetDictToNextPatrolPath();
private:
	std::vector<Point3<float> > m_patrolPath;
	uint32_t	m_nextPatrolPathIndex;
	bool		m_moveToTarget; //��������Ѳ��,���յ��ƶ�
	bool		m_isFinish; //����һ����Ѳ��
	int8_t   m_patroType; //Ѳ������
};

struct HateTargetData
{
	HateTargetData()
	{
		m_hateValue = 0;
		m_hateTargetCid = 0;
		m_hateTime = 0;
		m_damageValue = 0;
	}

	HateTargetData(const HateTargetData& data)
	{
		m_hateValue = data.m_hateValue;
		m_hateTargetCid = data.m_hateTargetCid;
		m_hateTime = data.m_hateTime;
		m_damageValue = data.m_damageValue;
	}

	bool operator<(const HateTargetData& data)
	{
		if (m_hateValue > data.m_hateValue)
		{
			return true;
		}
		else if (m_hateValue == data.m_hateValue)
		{
			if (m_hateTime < data.m_hateTime)
			{
				return true;
			}
		}
		return false;
	}

	uint32_t m_hateValue;
	CharIDType m_hateTargetCid;
	uint32_t m_damageValue; //
	uint64_t m_hateTime;
};

class AiData_ForHateList : public AiData_ForCreature
{
public:
	typedef std::list<HateTargetData>	HateTargetList;
public:
	AiData_ForHateList(Creature* master = nullptr) :AiData_ForCreature(master)
	{
		m_hateList.clear();
	}

	virtual ~AiData_ForHateList()
	{
		m_hateList.clear();
	}
public:
	void Clear() { m_hateList.clear(); }
	void ClearDeadAndInvisible();
	bool IsEmpty() { return m_hateList.empty(); }
	void AddHateTarget(CharIDType targetCid, int32_t hateValue, uint32_t damageValue);
	bool IsExistHateTarget(CharIDType targetCid);
	void RemoveHateTarget(CharIDType targetCid);
	void SortHateList();
	HateTargetList& GetHateList() { return m_hateList; }
private:
	HateTargetList m_hateList;
};

class AiData_ForPursuitTarget : public AiData_ForCreature
{
public:
	AiData_ForPursuitTarget(Creature* master = nullptr) :AiData_ForCreature(master)
	{
		Clear();
	}

	void Clear();
	bool IsReach();
	bool IsSkillChange(uint32_t skillId);
	//���˱Ƚ�׷��Ŀ���λ���Ƿ����
	bool IsChange(const Point3<float>& srcPos);
	void	SetTargetPos(const Point3<float>& srcPos) { m_targetPos = srcPos; }
	void	SetTargetSrcPos(const Point3<float>& srcPos) { m_targetSrcPos = srcPos;}
	void    SetPursuitSkillId(uint32_t skillId) { m_pursuitSkillId = skillId; }
	Point3<float> GetTargetPos() { return m_targetPos; }
private:
	uint64_t			m_changeTargetPosTime;
	Point3<float>	m_targetPos; //�ƶ�Ŀ�ĵ�
	Point3<float>	m_targetSrcPos; //׷��Ŀ��ĳ�ʼ����
	uint32_t		m_pursuitSkillId;
};

class HpStateInfo
{
public:
	HpStateInfo()
	{
		hpTrigger = false;
		hasDrop = true;
	}

	HpStateInfo(const HpStateInfo& info)
	{
		if (this == &info) return;
		CopyFrom(info);
	}

	HpStateInfo& operator=(const HpStateInfo& info)
	{
		if (this == &info) return *this;
		CopyFrom(info);
		return *this;
	}

	void CopyFrom(const HpStateInfo& stateInfo)
	{
		hpTrigger = stateInfo.hpTrigger;
		hasDrop = stateInfo.hasDrop;
		CopyFrom(stateInfo.info);
	}

	void CopyFrom(const AiAiHpPeriodCfgInfo& stateInfo)
	{
		info.AddSkills = stateInfo.AddSkills;
		info.Percentage = stateInfo.Percentage;
		info.RemoveSkills = stateInfo.RemoveSkills;
		info.Trigger = stateInfo.Trigger;
		info.Drop = stateInfo.Drop;
	}
public:
	bool hpTrigger;
	bool hasDrop;				//只能掉落一次
	AiAiHpPeriodCfgInfo   info;
};

class AiData_ForHPState : public AiData_ForCreature
{
public:
	AiData_ForHPState(Creature* master = nullptr) :AiData_ForCreature(master)
	{
		Clear();
	}

	void Clear();
public:
	bool HasHpStateNoTrigger();
	bool IsHpStateNoTrigger(int state);
	bool IsHpStateNeedTrigger(int state);
	void TriggerHpState(int state);
	void HandleTriggerHpState();
	void HandleStateSkill(int state);

	void ComputeAllTrigger();
public:
	std::vector<HpStateInfo> vecState;
	bool allTrigger;
};


